package clicktodial.model;

import java.util.List;
import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceUnit;
import javax.persistence.Query;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.transaction.UserTransaction;

public class ModelFacade implements ServletContextListener {
    
    @PersistenceUnit(unitName="ClickToDialPU")
    private EntityManagerFactory emf;
    
    @Resource
    private UserTransaction utx;
    
    /** Creates a new instance of ModelFacade */
    public ModelFacade() {}
    
    
    public void contextDestroyed(ServletContextEvent sce) {
        //close the factory and all entity managers associated with it
        if (emf.isOpen()) emf.close();
    }
    
    public void contextInitialized(ServletContextEvent sce) {
        ServletContext context = sce.getServletContext();
        context.setAttribute("Model", this);
    }  

    //public String addPerson(Person person, UserSignOn userSignOn){
    public String addPerson(Person person){
        EntityManager em = emf.createEntityManager();
        try{
            utx.begin();
            em.joinTransaction();
            em.persist(person);
            //em.persist(userSignOn);
            utx.commit();          
        } catch(Exception exe){
            try {
                utx.rollback();
            } catch (Exception e) {}
            throw new RuntimeException("Error persisting person", exe);
        } finally {
            em.close();
        }
        return person.getUsername();
    }
        
    @SuppressWarnings("unchecked")
    public List<Person> getAllPersons(){
        EntityManager em = emf.createEntityManager();
        List<Person> persons = em.createQuery("SELECT i FROM Person i").getResultList();
        em.close();
        return persons;
    }
    
    @SuppressWarnings("unchecked")
    public Person getPerson(String userName) {
        EntityManager em = emf.createEntityManager();
        Person person = em.find(Person.class, userName);
        em.close();
        return person;
    }

    @SuppressWarnings("unchecked")
    public Person updatePerson(Person person) {
        EntityManager em = emf.createEntityManager();
        try{
            utx.begin();
            em.merge(person);
            utx.commit();
        } catch(Exception exe){
            try {
                utx.rollback();
            } catch (Exception e) {}
            throw new RuntimeException("Error updating rating", exe);
        } finally {
            em.close();
        }
        return person;
    }
        
    @SuppressWarnings("unchecked")
    public void deletePerson(String userName) {
        EntityManager em = emf.createEntityManager();
        // TBD: this query needs to be changed to be a parameterized query for 
        // high performance
        Query q = em.createQuery("DELETE i FROM Person i WHERE userName = " + userName);
        q.executeUpdate();
    }
}
